package com.stellar.pay.core.service.impl;



import com.stellar.pay.config.WxPayConfig;
import com.stellar.pay.core.entity.PrepayResponse;
import com.stellar.pay.core.service.IWxPayJsapiService;
import com.stellar.pay.core.utils.IdempotentRequestChecker;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;


/**
 * @Author Jqcc
 * @Version 1.0
 * @Data 2025/4/4
 */
@Service
@Slf4j
@AllArgsConstructor
public class WxPayJsapiServiceImpl implements IWxPayJsapiService {

    private final WxPayConfig wxPayConfig;

    private final JsapiServiceExtension jsapiServiceExtension;


    @Override
    public PrepayResponse createOrder(String openId, String orderNo, BigDecimal totalAmount, String description) {

        // 幂等检查 - 5分钟内相同orderNo的请求视为重复
        if (IdempotentRequestChecker.isDuplicateRequest(orderNo)) {
            log.warn("重复支付请求 | orderNo:{}", orderNo);
            throw new RuntimeException("重复支付请求，请勿重复提交");
        }

        // 创建预支付请求参数
        PrepayRequest prepayRequest = new PrepayRequest();
        prepayRequest.setAppid(wxPayConfig.getAppId());
        prepayRequest.setMchid(wxPayConfig.getMchId());
        prepayRequest.setOutTradeNo(orderNo);
        prepayRequest.setDescription(description);
        prepayRequest.setNotifyUrl(wxPayConfig.getNotifyUrl());

        // 配置用户相关信息
        Payer payer = new Payer();
        payer.setOpenid(openId);
        prepayRequest.setPayer(payer);

        // 配置金额相关信息
        Amount amount = new Amount();
        amount.setTotal(totalAmount.multiply(new BigDecimal("100")).intValue()); // 订单总金额，单位为分
        amount.setCurrency("CNY");
        prepayRequest.setAmount(amount);

        // 发起预支付请求
        try {

            // 发起预支付请求,拿到预支付响应体
            PrepayWithRequestPaymentResponse prepayWithRequestPaymentResponse =
                    jsapiServiceExtension.prepayWithRequestPayment(prepayRequest);

            log.info("WxPayJsapiServiceImpl.createOrder.prepayWithRequestPaymentResponse.预支付响应体:{}", prepayWithRequestPaymentResponse);

            return new PrepayResponse(
                    prepayWithRequestPaymentResponse.getTimeStamp(),
                    prepayWithRequestPaymentResponse.getNonceStr(),
                    prepayWithRequestPaymentResponse.getPackageVal(),
                    prepayWithRequestPaymentResponse.getSignType(),
                    prepayWithRequestPaymentResponse.getPaySign()
            );
        } catch (Exception e) {
            log.error("微信支付预下单失败 | openId:{}, orderNo:{}", openId, orderNo, e);
            throw new RuntimeException("微信支付预下单失败", e);
        }
    }

}
